package com.top.ruizhong.main.video

import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Rect
import android.media.MediaMetadataRetriever
import android.net.Uri
import android.os.CountDownTimer
import android.util.Size
import android.view.Surface
import android.view.View
import androidx.camera.core.*
import androidx.camera.core.impl.PreviewConfig
import androidx.camera.core.impl.utils.Exif
import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.core.content.ContextCompat
import androidx.core.util.Consumer
import androidx.lifecycle.LifecycleOwner
import com.blankj.utilcode.util.FileUtils
import com.blankj.utilcode.util.ImageUtils
import com.blankj.utilcode.util.LogUtils
import com.blankj.utilcode.util.ScreenUtils
import com.google.common.util.concurrent.ListenableFuture
import com.module.lemlin.base.BaseAbstractActivity
import com.top.ruizhong.R
import com.top.ruizhong.mode.manager.getDiskCacheDirectoryBitmap
import com.top.ruizhong.mode.manager.getDiskCacheDirectoryVideo
import kotlinx.android.synthetic.main.activity_camera2.*
import java.io.BufferedInputStream
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.lang.StringBuilder
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors


@SuppressLint("RestrictedApi")
class XCamera2Activity : BaseAbstractActivity() {

    companion object {
        fun open(activity: Activity) {
            val intent = Intent(activity, XCamera2Activity::class.java)
            activity.startActivity(intent)
        }
    }

    override val layoutResId: Int
        get() = R.layout.activity_camera2

    override fun stateBar(): StatusBar {
        return StatusBar(
            isLightMode = false,
            color = R.color.colorBlack,
            bottomColor = R.color.colorBlack,
            view = cardView1
        )
    }

    private lateinit var cameraProviderFuture: ListenableFuture<ProcessCameraProvider>
    private lateinit var cameraProvider: ProcessCameraProvider
    private lateinit var preview: Preview
    private lateinit var cameraSelector: CameraSelector
    private lateinit var videoCapture: VideoCapture

    private var pathVideo: String? = null
    private var pathBitmap: String? = null

    private val fileBitmap: File
        get() = File(
            getDiskCacheDirectoryBitmap(this as Context).path,
            ("${System.currentTimeMillis()}.png")
        ).apply { pathBitmap = this.path }

    private val fileVideo: File
        get() = File(
            getDiskCacheDirectoryVideo(this as Context).path,
            ("${System.currentTimeMillis()}.mp4")
        ).apply { pathVideo = this.path }

    private val outputFileOptions: VideoCapture.OutputFileOptions
        get() = VideoCapture.OutputFileOptions.Builder(fileVideo).build()

    private val executorService: ExecutorService
        get() = Executors.newSingleThreadExecutor()

    private val videoSavedCallback: VideoCapture.OnVideoSavedCallback =
        object : VideoCapture.OnVideoSavedCallback {
            override fun onVideoSaved(outputFileResults: VideoCapture.OutputFileResults) {
                runOnUiThread {
                    setControllerView(isShoot = false)
                    unbindPreviewCamera()
                    bindPreviewVideo(outputFileResults.savedUri)

                    val save: String = outputFileResults.savedUri?.path
                        ?: return@runOnUiThread
                    val media = MediaMetadataRetriever()
                    media.setDataSource(save)
                    val originWidth: Int? =
                        media.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH)
                            ?.toInt()
                    val originHeight: Int? =
                        media.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT)
                            ?.toInt()

                    LogUtils.e("========originHeight:${originHeight}=======================originWidth:${originWidth}")

                    val file: File = fileBitmap
                    val bitmap: Bitmap = media.frameAtTime
                        ?: return@runOnUiThread
                    val fos = FileOutputStream(file)
                    bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos)
                    fos.flush()
                    fos.close()

                    val mBitmapFactory: BitmapFactory.Options = BitmapFactory.Options()
                    mBitmapFactory.inJustDecodeBounds = true
                    BitmapFactory.decodeFile(file.path, mBitmapFactory)
                    LogUtils.e("========originHeight:${mBitmapFactory.outHeight}=======================originWidth:${mBitmapFactory.outWidth}")


                }
            }

            override fun onError(videoCaptureError: Int, message: String, cause: Throwable?) {
                runOnUiThread { toast("视频录制错误:${message}") }
            }
        }

    private val millisInFuture: Long = 16 * 1000

    //计时器
    private val countDownTimer: CountDownTimer = object : CountDownTimer(millisInFuture, (1000)) {
        override fun onFinish() {
            stopRecording()
        }

        override fun onTick(millisUntilFinished: Long) {
            val second: Long = (millisInFuture - millisUntilFinished) / 1000
            val secondStr: String = if (second.toString().length == 1)
                "0${second}" else second.toString()
            tvCameraDownTime.text = StringBuilder()
                .append("00:").append(secondStr)

            if (second == 0L) startRecording()
        }
    }

    override fun initView() {

        ivCameraBack.setOnClickListener { this.finish() }

//        //删除视频缓存目录中文件
        FileUtils.deleteAllInDir(
            getDiskCacheDirectoryVideo(
                this as Context
            )
        )

        cameraProviderFuture = ProcessCameraProvider.getInstance(this)
        cameraProviderFuture.addListener(Runnable {
            cameraProvider = cameraProviderFuture.get()
            bindPreviewCamera()
        }, ContextCompat.getMainExecutor(this as Context))


        //切换摄像头
        ivCameraFacing.setOnClickListener {
            var facing: Int = cameraSelector.lensFacing
                ?: CameraSelector.LENS_FACING_BACK
            facing = if (facing == CameraSelector.LENS_FACING_BACK) {
                CameraSelector.LENS_FACING_FRONT
            } else {
                CameraSelector.LENS_FACING_BACK
            }
            bindPreviewCamera(facing)
        }

        //开始与暂停录制视频
        rbCameraShoot.setOnClickListener {
            if (rbCameraShoot.isChecked) {
                startDownTimer()
            } else {
                stopDownTimer()
            }
        }

        //放弃已录制视频
        ivCameraVideoNo.setOnClickListener {
            unbindPreviewVideo()
            bindPreviewCamera()
            setControllerView(isShoot = true)
            FileUtils.delete(pathVideo)
        }

        //选中该视频
        ivCameraVideoYes.setOnClickListener {
            if (pathBitmap != null && pathVideo != null) {
                VideoEditingActivity.openEditing(
                    activity = this, pathVideo = pathVideo!!, pathBitmap = pathBitmap!!
                )

//                VideoEditingActivity.openEditing(
//                    activity = this,
//                    pathVideo = File(getExternalCacheDir(), "demo2.mp4").path,
//                    pathBitmap = pathBitmap!!
//                )
            }
        }

        //视频播放完成回调
        mVideoView.setOnCompletionListener {
            it.start()
            it.isLooping = true
        }

    }

    override fun onRestart() {
        super.onRestart()
        bindPreviewVideo(Uri.parse(pathVideo))
    }

    override fun onStop() {
        super.onStop()
        stopDownTimer()
    }

    override fun onDestroy() {
        super.onDestroy()
        release()
    }

    /**
     * 设置控制器视图
     * */
    private fun setControllerView(isShoot: Boolean) {
        tvCameraDownTime.text = "点击录制"
        rbCameraShoot.visibility = if (isShoot) View.VISIBLE else View.INVISIBLE
        llCameraDownTime.visibility = if (isShoot) View.VISIBLE else View.INVISIBLE
        ivCameraFacing.visibility = if (isShoot) View.VISIBLE else View.GONE
        ivCameraVideoYes.visibility = if (isShoot) View.GONE else View.VISIBLE
        ivCameraVideoNo.visibility = if (isShoot) View.GONE else View.VISIBLE
    }

    /**
     * 绑定相机预览
     * */
    private fun bindPreviewCamera(@CameraSelector.LensFacing lensFacing: Int = CameraSelector.LENS_FACING_BACK) {


        preview = Preview.Builder()
            .setTargetAspectRatio(AspectRatio.RATIO_16_9)
            .setTargetRotation(pvPreviewCamera.display.rotation)
            .build()
        preview.setSurfaceProvider(pvPreviewCamera.surfaceProvider)

        videoCapture = VideoCapture.Builder()
            .setTargetAspectRatio(AspectRatio.RATIO_16_9)
            .setTargetRotation(pvPreviewCamera.display.rotation)
            .setBitRate(1024 * 1024 * 3)
            .setVideoFrameRate(25)
            .build()

        cameraSelector = CameraSelector.Builder()
            .requireLensFacing(lensFacing)
            .build()

        cameraProvider.unbindAll()
        cameraProvider.bindToLifecycle(
            this as LifecycleOwner, cameraSelector, videoCapture, preview
        )
    }

    /**
     * 解绑相机预览
     * */
    private fun unbindPreviewCamera() {
        cameraProvider.unbindAll()
    }

    /**
     * 绑定视频播放并显示
     * */
    private fun bindPreviewVideo(uri: Uri?) {
        mVideoView.visibility = View.VISIBLE
        mVideoView.setVideoURI(uri)
        mVideoView.start()


    }

    /**
     * 停止视频播放并释放隐藏
     * */
    private fun unbindPreviewVideo() {
        mVideoView.visibility = View.INVISIBLE
        mVideoView.stopPlayback()

    }

    /**
     * 彻底释放播放器与解除相机绑定
     * */
    private fun release() {
        mVideoView.suspend()
        cameraProvider.unbindAll()
    }

    /**
     * 开始录制视频
     * */
    private fun startRecording() {
        ivCameraFacing.visibility = View.GONE

        videoCapture.startRecording(
            outputFileOptions, executorService, videoSavedCallback
        )
    }

    /**
     * 结束录制视频
     * */
    private fun stopRecording() {
        rbCameraShoot.isChecked = false
        videoCapture.stopRecording()
    }

    /**
     * 开始拍摄计时
     * */
    private fun startDownTimer() {
        countDownTimer.start()
    }

    /**
     * 停止拍摄计时
     * */
    private fun stopDownTimer() {
        countDownTimer.cancel()
        countDownTimer.onFinish()
    }
}